package org.example;

import java.util.concurrent.TimeUnit;

/**
 * 模拟并发订票
 */
public class SaleTicketDemo01 {
    public static void main(String[] args) {
        // 创建资源类，将资源类丢进线程
        Ticket ticket = new Ticket();
        new Thread(() -> { for (int i = 0; i < 10; i++) ticket.sale(); }, "A").start();
        new Thread(() -> { for (int i = 0; i < 10; i++) ticket.sale(); }, "B").start();
        new Thread(() -> { for (int i = 0; i < 10; i++) ticket.sale(); }, "C").start();

        /* 不加锁情况：
         售票员B	出售第30张票	剩余29张
         售票员A	出售第30张票	剩余29张
         售票员C	出售第30张票	剩余29张
         现象解释：根据JMM内存模型，因为每个线程在自己的本地内存中都有一份变量副本，当多个线程同时修改一个资源时，
                  每个线程只是修改本地的副本，还未刷新到主内存中，导致数据未及时同步
         解决思路：将资源上锁，每次只允许被一个线程修改
         */
    }
}

/**
 * 资源类 OOP
 * 降低耦合度
 */
class Ticket {
    // 属性、方法
    private int TICKET_NUM = 30;

    // 出售车票业务代码
    public synchronized void sale() {   // 通过synchronized实现同步
        System.out.println(Thread.currentThread().getName() + "出售第" + (TICKET_NUM--) + "张票，剩余：" + TICKET_NUM);
        try {
            // 修改-刷新延时，增加冲突率
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}